home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
mail.altrad.com
/
2015.02.mail.altrad.com.tar
/
mail.altrad.com
/
TEST
/
office german
/
PROPLUS.WW
/
PROPLSWW.CAB
/
OMML2MML.XSL
< prev
next >
Wrap
Extensible Markup Language
|
2006-08-27
|
54KB
|
1,312 lines
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mml="http://www.w3.org/1998/Math/MathML"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math">
<xsl:output method="xml" encoding="UTF-16" />
<!-- %% Global Definitions -->
<!-- Every single unicode character that is recognized by OMML as an operator -->
<xsl:variable name="sOperators"
select="concat(
'!"()+,-/⫾:;<',
'=>?[\]{|}¡¬±',
'·¿×÷ ',
' ‐‒–—‖†‡•․‥…',
'‼⁀⁎⁏⁐ ⅀←↑',
'→↓↔↕↖↗↘↙↚↛↜↝',
'↞↟↠↡↢↣↤↥↦↧↨↩',
'↪↫↬↭↮↯↰↱↲↳↶↷',
'↺↻↼↽↾↿⇀⇁⇂⇃⇄⇅',
'⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑',
'⇒⇓⇔⇕⇖⇗⇘⇙⇚⇛⇜⇝',
'⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩',
'⇴⇵⇶⇷⇸⇹⇺⇻⇼⇽⇾⇿',
'∀∁∂∃∄∆∇∈∉∊∋∌',
'∍∏∐∑−∓∔∕∖∗∘∙',
'√∛∜∝∣∤∥∦∧∨∩∪',
'∫∬∭∮∯∰∱∲∳∴∵∶',
'∷∸∹∺∻∼∽∾≀≁≂≃',
'≄≅≆≇≈≉≊≋≌≍≎≏',
'≐≑≒≓≔≕≖≗≘≙≚≛',
'≜≝≞≟≠≡≢≣≤≥≦≧',
'≨≩≪≫≬≭≮≯≰≱≲≳',
'≴≵≶≷≸≹≺≻≼≽≾≿',
'⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋',
'⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗',
'⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣',
'⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰',
'⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼',
'⊽⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊',
'⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖',
'⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢',
'⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮',
'⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺',
'⋻⋼⋽⋾⋿⌅⌆⌈⌉⌊⌋⌜',
'⌝⌞⌟⌢⌣〈〉⌽⌿⎰⎱▲',
'△▴▵▶▷▸▹▼▽▾▿◀',
'◁◂◃◄◅◊○◦◫◬◸◹',
'◺◻◼◽◾◿★☆❲❳⟑⟒',
'⟓⟔⟕⟖⟗⟘⟙⟚⟛⟜⟝⟞',
'⟟⟠⟡⟢⟣⟤⟥⟦⟧⟨⟩⟪',
'⟫⟰⟱⟲⟳⟴⟵⟶⟷⟸⟹⟺',
'⟻⟼⟽⟾⟿⤀⤁⤂⤃⤄⤅⤆',
'⤇⤈⤉⤊⤋⤌⤍⤎⤏⤐⤑⤒',
'⤓⤔⤕⤖⤗⤘⤙⤚⤛⤜⤝⤞',
'⤟⤠⤡⤢⤣⤤⤥⤦⤧⤨⤩⤪',
'⤫⤬⤭⤮⤯⤰⤱⤲⤳⤴⤵⤶',
'⤷⤸⤹⤺⤻⤼⤽⤾⤿⥀⥁⥂',
'⥃⥄⥅⥆⥇⥈⥉⥊⥋⥌⥍⥎',
'⥏⥐⥑⥒⥓⥔⥕⥖⥗⥘⥙⥚',
'⥛⥜⥝⥞⥟⥠⥡⥢⥣⥤⥥⥦',
'⥧⥨⥩⥪⥫⥬⥭⥮⥯⥰⥱⥲',
'⥳⥴⥵⥶⥷⥸⥹⥺⥻⥼⥽⥾',
'⥿⦀⦂⦃⦄⦅⦆⦇⦈⦉⦊⦋',
'⦌⦍⦎⦏⦐⦑⦒⦓⦔⦕⦖⦗',
'⦘⦙⦚⦶⦷⦸⦹⧀⧁⧄⧅⧆',
'⧇⧈⧎⧏⧐⧑⧒⧓⧔⧕⧖⧗',
'⧘⧙⧚⧛⧟⧡⧢⧣⧤⧥⧦⧫',
'⧴⧵⧶⧷⧸⧹⧺⧻⧼⧽⧾⧿',
'⨀⨁⨂⨃⨄⨅⨆⨇⨈⨉⨊⨋',
'⨌⨍⨎⨏⨐⨑⨒⨓⨔⨕⨖⨗',
'⨘⨙⨚⨛⨜⨝⨞⨟⨠⨡⨢⨣',
'⨤⨥⨦⨧⨨⨩⨪⨫⨬⨭⨮⨯',
'⨰⨱⨲⨳⨴⨵⨶⨷⨸⨹⨺⨻',
'⨼⨽⨾⨿⩀⩁⩂⩃⩄⩅⩆⩇',
'⩈⩉⩊⩋⩌⩍⩎⩏⩐⩑⩒⩓',
'⩔⩕⩖⩗⩘⩙⩚⩛⩜⩝⩞⩟',
'⩠⩡⩢⩣⩤⩥⩦⩧⩨⩩⩪⩫',
'⩬⩭⩮⩯⩰⩱⩲⩳⩴⩵⩶⩷',
'⩸⩹⩺⩻⩼⩽⩾⩿⪀⪁⪂⪃',
'⪄⪅⪆⪇⪈⪉⪊⪋⪌⪍⪎⪏',
'⪐⪑⪒⪓⪔⪕⪖⪗⪘⪙⪚⪛',
'⪜⪝⪞⪟⪠⪡⪢⪣⪤⪥⪦⪧',
'⪨⪩⪪⪫⪬⪭⪮⪯⪰⪱⪲⪳',
'⪴⪵⪶⪷⪸⪹⪺⪻⪼⪽⪾⪿',
'⫀⫁⫂⫃⫄⫅⫆⫇⫈⫉⫊⫋',
'⫌⫍⫎⫏⫐⫑⫒⫓⫔⫕⫖⫗',
'⫘⫙⫚⫛⫝̸⫝⫞⫟⫠⫢⫣⫤',
'⫥⫦⫧⫨⫩⫪⫫⫬⫭⫮⫯⫰',
'⫲⫳⫴⫵⫶⫷⫸⫹⫺⫻⫼⫽')" />
<!-- A string of '-'s repeated exactly as many times as the operators above -->
<xsl:variable name="sMinuses">
<xsl:call-template name="SRepeatChar">
<xsl:with-param name="cchRequired" select="string-length($sOperators)" />
<xsl:with-param name="ch" select="'-'" />
</xsl:call-template>
</xsl:variable>
<!-- Every single unicode character that is recognized by OMML as a number -->
<xsl:variable name="sNumbers" select="'0123456789'"/>
<!-- A string of '0's repeated exactly as many times as the list of numbers above -->
<xsl:variable name="sZeros">
<xsl:call-template name="SRepeatChar">
<xsl:with-param name="cchRequired" select="string-length($sNumbers)" />
<xsl:with-param name="ch" select="'0'" />
</xsl:call-template>
</xsl:variable>
<!-- %%Template: SReplace
Replace all occurences of sOrig in sInput with sReplacement
and return the resulting string. -->
<xsl:template name="SReplace">
<xsl:param name="sInput" />
<xsl:param name="sOrig" />
<xsl:param name="sReplacement" />
<xsl:choose>
<xsl:when test="not(contains($sInput, $sOrig))">
<xsl:value-of select="$sInput" />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="sBefore" select="substring-before($sInput, $sOrig)" />
<xsl:variable name="sAfter" select="substring-after($sInput, $sOrig)" />
<xsl:variable name="sAfterProcessed">
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sAfter" />
<xsl:with-param name="sOrig" select="$sOrig" />
<xsl:with-param name="sReplacement" select="$sReplacement" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat($sBefore, concat($sReplacement, $sAfterProcessed))" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Templates -->
<xsl:template match="/">
<mml:math>
<xsl:apply-templates select="*" />
</mml:math>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates select="*" />
</xsl:template>
<xsl:template match="m:acc">
<mml:mover>
<xsl:attribute name="accent">true</xsl:attribute>
<xsl:apply-templates select="m:e[1]" />
<mml:mtext>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" select="m:e[1]/*/m:rPr[last()]/m:scr/@m:val" />
<xsl:with-param name="sty" select="m:e[1]/*/m:rPr[last()]/m:sty/@m:val" />
<xsl:with-param name="nor" select="m:e[1]/*/m:rPr[last()]/m:nor/@m:val" />
</xsl:call-template>
<xsl:choose>
<xsl:when test="not(m:accPr[last()]/m:chr)">
<xsl:value-of select="'̂'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring(m:accPr/m:chr/@m:val,1,1)" />
</xsl:otherwise>
</xsl:choose>
</mml:mtext>
</mml:mover>
</xsl:template>
<xsl:template match="m:sPre">
<mml:mmultiscripts>
<mml:mrow>
<xsl:apply-templates select="m:e[1]" />
</mml:mrow>
<mml:mprescripts />
<mml:mrow>
<xsl:apply-templates select="m:sub[1]" />
</mml:mrow>
<mml:mrow>
<xsl:apply-templates select="m:sup[1]" />
</mml:mrow>
</mml:mmultiscripts>
</xsl:template>
<xsl:template match="m:m">
<mml:mtable>
<xsl:call-template name="CreateMathMLMatrixAttr">
<xsl:with-param name="mcJc" select="m:mPr[last()]/m:mcs/m:mc/m:mcPr[last()]/m:mcJc/@m:val" />
</xsl:call-template>
<xsl:for-each select="m:mr">
<mml:mtr>
<xsl:for-each select="m:e">
<mml:mtd>
<xsl:apply-templates select="." />
</mml:mtd>
</xsl:for-each>
</mml:mtr>
</xsl:for-each>
</mml:mtable>
</xsl:template>
<xsl:template name="CreateMathMLMatrixAttr">
<xsl:param name="mcJc" />
<xsl:variable name="sLowerCaseMcjc" select="translate($mcJc, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:choose>
<xsl:when test="$sLowerCaseMcjc='left'">
<xsl:attribute name="columnalign">left</xsl:attribute>
</xsl:when>
<xsl:when test="$sLowerCaseMcjc='right'">
<xsl:attribute name="columnalign">right</xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="m:phant">
<xsl:variable name="sLowerCaseWidth" select="translate(m:phantPr[last()]/m:width/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseAsc" select="translate(m:phantPr[last()]/m:asc/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseDec" select="translate(m:phantPr[last()]/m:dec/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:if test="not($sLowerCaseWidth='off' and
$sLowerCaseAsc='off' and
$sLowerCaseDec='off')">
<mml:phantom>
<xsl:apply-templates select="m:e[1]" />
</mml:phantom>
</xsl:if>
</xsl:template>
<xsl:template match="m:rad">
<xsl:variable name="sLowerCaseDegHide" select="translate(m:radPr[last()]/m:degHide/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:choose>
<xsl:when test="$sLowerCaseDegHide='on'">
<mml:msqrt>
<xsl:apply-templates select="m:e[1]" />
</mml:msqrt>
</xsl:when>
<xsl:otherwise>
<mml:mroot>
<mml:mrow>
<xsl:apply-templates select="m:e[1]" />
</mml:mrow>
<mml:mrow>
<xsl:apply-templates select="m:deg[1]" />
</mml:mrow>
</mml:mroot>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template match m:nary
Process an n-ary.
Decides, based on which arguments are supplied, between
using an mo, msup, msub, or msubsup for the n-ary operator
-->
<xsl:template match="m:nary">
<xsl:variable name="sLowerCaseSubHide">
<xsl:choose>
<xsl:when test="count(m:naryPr[last()]/m:subHide) = 0">
<xsl:text>off</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate(m:naryPr[last()]/m:subHide/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="sLowerCaseSupHide">
<xsl:choose>
<xsl:when test="count(m:naryPr[last()]/m:supHide) = 0">
<xsl:text>off</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate(m:naryPr[last()]/m:supHide/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="not($sLowerCaseSupHide='off') and
not($sLowerCaseSubHide='off')">
<mml:mo>
<xsl:choose>
<xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or
m:naryPr[last()]/m:chr/@m:val=''">
<xsl:text disable-output-escaping="yes">∫</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" />
</xsl:otherwise>
</xsl:choose>
</mml:mo>
</xsl:when>
<xsl:when test="not($sLowerCaseSubHide='off')">
<xsl:choose>
<xsl:when test="m:naryPr[last()]/m:limLoc/@m:val='subSup'">
<mml:msup>
<mml:mo>
<xsl:choose>
<xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or
m:naryPr[last()]/m:chr/@m:val=''">
<xsl:text disable-output-escaping="yes">∫</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" />
</xsl:otherwise>
</xsl:choose>
</mml:mo>
<xsl:apply-templates select="m:sup[1]" />
</mml:msup>
</xsl:when>
<xsl:otherwise>
<mml:mover>
<mml:mo>
<xsl:choose>
<xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or
m:naryPr[last()]/m:chr/@m:val=''">
<xsl:text disable-output-escaping="yes">∫</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" />
</xsl:otherwise>
</xsl:choose>
</mml:mo>
<xsl:apply-templates select="m:sup[1]" />
</mml:mover>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="not($sLowerCaseSupHide='off')">
<xsl:choose>
<xsl:when test="m:naryPr[last()]/m:limLoc/@m:val='subSup'">
<mml:msub>
<mml:mo>
<xsl:choose>
<xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or
m:naryPr[last()]/m:chr/@m:val=''">
<xsl:text disable-output-escaping="yes">∫</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" />
</xsl:otherwise>
</xsl:choose>
</mml:mo>
<xsl:apply-templates select="m:sub[1]" />
</mml:msub>
</xsl:when>
<xsl:otherwise>
<mml:munder>
<mml:mo>
<xsl:choose>
<xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or
m:naryPr[last()]/m:chr/@m:val=''">
<xsl:text disable-output-escaping="yes">∫</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" />
</xsl:otherwise>
</xsl:choose>
</mml:mo>
<xsl:apply-templates select="m:sub[1]" />
</mml:munder>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="m:naryPr[last()]/m:limLoc/@m:val='subSup'">
<mml:msubsup>
<mml:mo>
<xsl:choose>
<xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or
m:naryPr[last()]/m:chr/@m:val=''">
<xsl:text disable-output-escaping="yes">∫</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" />
</xsl:otherwise>
</xsl:choose>
</mml:mo>
<xsl:apply-templates select="m:sub[1]" />
<xsl:apply-templates select="m:sup[1]" />
</mml:msubsup>
</xsl:when>
<xsl:otherwise>
<mml:munderover>
<mml:mo>
<xsl:choose>
<xsl:when test="not(m:naryPr[last()]/m:chr/@m:val) or
m:naryPr[last()]/m:chr/@m:val=''">
<xsl:text disable-output-escaping="yes">∫</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="m:naryPr[last()]/m:chr/@m:val" />
</xsl:otherwise>
</xsl:choose>
</mml:mo>
<xsl:apply-templates select="m:sub[1]" />
<xsl:apply-templates select="m:sup[1]" />
</mml:munderover>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
<mml:mrow>
<xsl:apply-templates select="m:e[1]" />
</mml:mrow>
</xsl:template>
<xsl:template match="m:limLow">
<mml:munder>
<mml:mrow>
<xsl:apply-templates select="m:e[1]" />
</mml:mrow>
<mml:mrow>
<xsl:apply-templates select="m:lim[1]" />
</mml:mrow>
</mml:munder>
</xsl:template>
<xsl:template match="m:limUpp">
<mml:mover>
<mml:mrow>
<xsl:apply-templates select="m:e[1]" />
</mml:mrow>
<mml:mrow>
<xsl:apply-templates select="m:lim[1]" />
</mml:mrow>
</mml:mover>
</xsl:template>
<xsl:template match="m:sSub">
<mml:msub>
<mml:mrow>
<xsl:apply-templates select="m:e[1]" />
</mml:mrow>
<mml:mrow>
<xsl:apply-templates select="m:sub[1]" />
</mml:mrow>
</mml:msub>
</xsl:template>
<xsl:template match="m:sSup">
<mml:msup>
<mml:mrow>
<xsl:apply-templates select="m:e[1]" />
</mml:mrow>
<mml:mrow>
<xsl:apply-templates select="m:sup[1]" />
</mml:mrow>
</mml:msup>
</xsl:template>
<xsl:template match="m:sSubSup">
<mml:msubsup>
<mml:mrow>
<xsl:apply-templates select="m:e[1]" />
</mml:mrow>
<mml:mrow>
<xsl:apply-templates select="m:sub[1]" />
</mml:mrow>
<mml:mrow>
<xsl:apply-templates select="m:sup[1]" />
</mml:mrow>
</mml:msubsup>
</xsl:template>
<xsl:template match="m:groupChr">
<xsl:variable name="sLowerCaseOpEmu" select="translate(m:groupChrPr[last()]/m:opEmu/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:choose>
<xsl:when test="$sLowerCaseOpEmu='on'">
<mml:mrow>
<xsl:call-template name="CreateGroupChr" />
</mml:mrow>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CreateGroupChr" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="CreateGroupChr">
<xsl:variable name="sLowerCasePos" select="translate(m:groupChrPr[last()]/m:pos/@m:val,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:choose>
<xsl:when test="$sLowerCasePos!='top' or
not(m:groupChrPr[last()]/m:pos/@m:val) or
m:groupChrPr[last()]/m:pos/@m:val=''">
<mml:munder>
<xsl:apply-templates select="m:e[1]" />
<mml:mo>
<xsl:choose>
<xsl:when test="string-length(m:groupChrPr[last()]/m:chr/@m:val) >= 1">
<xsl:value-of select="substring(m:groupChrPr[last()]/m:chr/@m:val,1,1)" />
</xsl:when>
<xsl:otherwise>
<xsl:text disable-output-escaping="yes">⏟</xsl:text>
</xsl:otherwise>
</xsl:choose>
</mml:mo>
</mml:munder>
</xsl:when>
<xsl:otherwise>
<mml:mover>
<xsl:apply-templates select="m:e[1]" />
<mml:mo>
<xsl:choose>
<xsl:when test="string-length(m:groupChrPr[last()]/m:chr/@m:val) >= 1">
<xsl:value-of select="substring(m:groupChrPr[last()]/m:chr/@m:val,1,1)" />
</xsl:when>
<xsl:otherwise>
<xsl:text disable-output-escaping="yes">⏟</xsl:text>
</xsl:otherwise>
</xsl:choose>
</mml:mo>
</mml:mover>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="fName">
<xsl:for-each select="m:fName/*">
<xsl:apply-templates select="." />
</xsl:for-each>
</xsl:template>
<xsl:template match="m:func">
<mml:mrow>
<mml:mrow>
<xsl:call-template name="fName" />
</mml:mrow>
<mml:mo></mml:mo>
<xsl:apply-templates select="*[position() > 1]" />
</mml:mrow>
</xsl:template>
<!-- %%Template: match m:f
m:f maps directly to mfrac.
-->
<xsl:template match="m:f">
<mml:mfrac>
<xsl:call-template name="CreateMathMLFracProp">
<xsl:with-param name="type" select="m:fPr[last()]/m:type/@m:val" />
<xsl:with-param name="baseJc" select="m:fPr[last()]/m:baseJc/@m:val" />
<xsl:with-param name="numJc" select="m:fPr[last()]/m:numJc/@m:val" />
<xsl:with-param name="denJc" select="m:fPr[last()]/m:type/@m:val" />
</xsl:call-template>
<mml:mrow><xsl:apply-templates select="m:num[1]" /></mml:mrow>
<mml:mrow><xsl:apply-templates select="m:den[1]" /></mml:mrow>
</mml:mfrac>
</xsl:template>
<!-- %%Template: CreateMathMLFracProp
Make fraction properties based on supplied parameters.
OMML differentiates between a linear fraction and a skewed
one. For MathML, we write both as bevelled.
-->
<xsl:template name="CreateMathMLFracProp">
<xsl:param name="type" />
<xsl:param name="baseJc" />
<xsl:param name="numJc" />
<xsl:param name="denJc" />
<xsl:variable name="sLowerCaseType" select="translate($type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseNumJc" select="translate($numJc, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="sLowerCaseDenJc" select="translate($denJc, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
<xsl:if test="$sLowerCaseType='skw' or $sLowerCaseType='lin'">
<xsl:attribute name="bevelled">true</xsl:attribute>
</xsl:if>
<xsl:if test="$sLowerCaseType='nobar'">
<xsl:attribute name="linethickness">0pt</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="sLowerCaseNumJc='right'">
<xsl:attribute name="numalign">right</xsl:attribute>
</xsl:when>
<xsl:when test="sLowerCaseNumJc='left'">
<xsl:attribute name="numalign">left</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="sLowerCaseDenJc='right'">
<xsl:attribute name="numalign">right</xsl:attribute>
</xsl:when>
<xsl:when test="sLowerCaseDenJc='left'">
<xsl:attribute name="numalign">left</xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- %%Template: match m:e | m:den | m:num | m:lim | m:sup | m:sub
These element delinate parts of an equation (like the numerator). -->
<xsl:template match="m:e | m:den | m:num | m:lim | m:sup | m:sub">
<xsl:choose>
<!-- If there is no scriptLevel speified, just call through -->
<xsl:when test="not(m:argPr[last()]/m:scrLvl/@m:val)">
<xsl:apply-templates select="*" />
</xsl:when>
<!-- Otherwise, create an mstyle and set the script level -->
<xsl:otherwise>
<mml:mstyle>
<xsl:attribute name="scriptlevel">
<xsl:value-of select="m:argPr[last()]/m:scrLvl/@m:val" />
</xsl:attribute>
<xsl:apply-templates select="*" />
</mml:mstyle>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="m:bar">
<xsl:variable name="sLowerCasePos" select="translate(m:barPr/m:pos/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:choose>
<xsl:when test="$sLowerCasePos!='bot' or
not($sLowerCasePos) or
$sLowerCasePos='' ">
<mml:mover>
<xsl:attribute name="accent">true</xsl:attribute>
<xsl:apply-templates select="m:e[1]" />
<mml:mo>
<xsl:text disable-output-escaping="yes">¯</xsl:text>
</mml:mo>
</mml:mover>
</xsl:when>
<xsl:otherwise>
<mml:munder>
<xsl:apply-templates select="m:e[1]" />
<mml:mo>
<xsl:text disable-output-escaping="yes">̲</xsl:text>
</mml:mo>
</mml:munder>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template match m:d
Process a delimiter.
-->
<xsl:template match="m:d">
<mml:mfenced>
<!-- open: default is ( for both OMML and MathML -->
<xsl:if test="m:dPr[1]/m:begChr/@m:val and not(m:dPr[1]/m:begChr/@m:val ='(')">
<xsl:attribute name="open">
<xsl:value-of select="m:dPr[1]/m:begChr/@m:val" />
</xsl:attribute>
</xsl:if>
<!-- close: default is ) for both OMML and MathML -->
<xsl:if test="m:dPr[1]/m:endChr/@m:val and not(m:dPr[1]/m:endChr/@m:val =')')">
<xsl:attribute name="close">
<xsl:value-of select="m:dPr[1]/m:endChr/@m:val" />
</xsl:attribute>
</xsl:if>
<!-- separator: the default is ',' for MathML, and '|' for OMML -->
<xsl:choose>
<!-- Matches MathML default. Write nothing -->
<xsl:when test="m:dPr[1]/m:sepChr/@m:val = ','" />
<!-- OMML default: | -->
<xsl:when test="not(m:dPr[1]/m:sepChr/@m:val)">
<xsl:attribute name="separators">
<xsl:value-of select="'|'" />
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="separators">
<xsl:value-of select="m:dPr[1]/m:sepChr/@m:val" />
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<!-- now write all the children. Put each one into an mrow
just in case it produces multiple runs, etc -->
<xsl:for-each select="m:e">
<mml:mrow>
<xsl:apply-templates select="." />
</mml:mrow>
</xsl:for-each>
</mml:mfenced>
</xsl:template>
<xsl:template match="m:r">
<xsl:variable name="sLowerCaseNor" select="translate(child::m:rPr[last()]/m:nor/@m:val, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:choose>
<xsl:when test="$sLowerCaseNor='on'">
<mml:mtext>
<xsl:value-of select=".//m:t" />
</mml:mtext>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select=".//m:t">
<xsl:call-template name="ParseMt">
<xsl:with-param name="sToParse" select="text()" />
<xsl:with-param name="scr" select="../m:rPr[last()]/m:scr/@m:val" />
<xsl:with-param name="sty" select="../m:rPr[last()]/m:sty/@m:val" />
<xsl:with-param name="nor" select="../m:rPr[last()]/m:nor/@m:val" />
</xsl:call-template>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="CreateTokenAttributes">
<xsl:param name="scr" />
<xsl:param name="sty" />
<xsl:param name="nor" />
<xsl:param name="nCharToPrint" />
<xsl:param name="sTokenType" />
<xsl:variable name="sLowerCaseNor" select="translate($nor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:choose>
<xsl:when test="$sLowerCaseNor = 'on'">
<xsl:attribute name="mathvariant">normal</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="mathvariant">
<xsl:choose>
<!-- numbers don't care -->
<xsl:when test="$sTokenType='mn'" />
<xsl:when test="$scr='monospace'">monospace</xsl:when>
<xsl:when test="$scr='sans-serif' and $sty='i'">sans-serif-italic</xsl:when>
<xsl:when test="$scr='sans-serif' and $sty='b'">bold-sans-serif</xsl:when>
<xsl:when test="$scr='sans-serif'">sans-serif</xsl:when>
<xsl:when test="$scr='fraktur' and $sty='b'">bold-fraktur</xsl:when>
<xsl:when test="$scr='fraktur'">fraktur</xsl:when>
<xsl:when test="$scr='double-struck'">double-struck</xsl:when>
<xsl:when test="$scr='script' and $sty='b'">bold-script</xsl:when>
<xsl:when test="$scr='script'">script</xsl:when>
<xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='b'">bold</xsl:when>
<xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='i'">italic</xsl:when>
<xsl:when test="($scr='roman' or not($scr) or $scr='') and $sty='p'">normal</xsl:when>
<xsl:otherwise />
</xsl:choose>
</xsl:variable>
<xsl:variable name="fontweight">
<xsl:choose>
<xsl:when test="$sty='b' or $sty='bi'">bold</xsl:when>
<xsl:otherwise>normal</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fontstyle">
<xsl:choose>
<xsl:when test="$sty='p' or $sty='b'">normal</xsl:when>
<xsl:otherwise>italic</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Writing of attributes begins here -->
<xsl:choose>
<!-- Don't write mathvariant for operators unless they want to be normal -->
<xsl:when test="$sTokenType='mo' and $mathvariant!='normal'" />
<!-- A single character within an mi is already italics, don't write -->
<xsl:when test="$sTokenType='mi' and $nCharToPrint=1 and ($mathvariant='' or $mathvariant='italic')" />
<xsl:when test="$sTokenType='mi' and $nCharToPrint > 1 and ($mathvariant='' or $mathvariant='italic')">
<xsl:attribute name="mathvariant">
<xsl:value-of select="'italic'" />
</xsl:attribute>
</xsl:when>
<xsl:when test="$mathvariant!='italic' and $mathvariant!=''">
<xsl:attribute name="mathvariant">
<xsl:value-of select="$mathvariant" />
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:if test="not($sTokenType='mi' and $nCharToPrint=1) and $fontstyle='italic'">
<xsl:attribute name="fontstyle">italic</xsl:attribute>
</xsl:if>
<xsl:if test="$fontweight='bold'">
<xsl:attribute name="fontweight">bold</xsl:attribute>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="m:eqArr">
<mml:mtable>
<xsl:attribute name="frame">none</xsl:attribute>
<xsl:attribute name="columnlines">none</xsl:attribute>
<xsl:attribute name="rowlines">none</xsl:attribute>
<xsl:for-each select="m:e">
<mml:mtr>
<mml:mtd>
<mml:maligngroup />
<xsl:choose>
<xsl:when test="m:argPr[last()]/m:scrLvl/@m:val!='0' or
not(m:argPr[last()]/m:scrLvl/@m:val) or
m:argPr[last()]/m:scrLvl/@m:val=''">
<mml:mrow>
<xsl:call-template name="CreateEqArrRow">
<xsl:with-param name="align" select="1" />
<xsl:with-param name="ndCur" select="*[1]" />
</xsl:call-template>
</mml:mrow>
</xsl:when>
<xsl:otherwise>
<mml:mstyle>
<xsl:attribute name="scriptlevel">
<xsl:value-of select="m:argPr[last()]/m:scrLvl/@m:val" />
</xsl:attribute>
<xsl:call-template name="CreateEqArrRow">
<xsl:with-param name="align" select="1" />
<xsl:with-param name="ndCur" select="*[1]" />
</xsl:call-template>
</mml:mstyle>
</xsl:otherwise>
</xsl:choose>
</mml:mtd>
</mml:mtr>
</xsl:for-each>
</mml:mtable>
</xsl:template>
<xsl:template name="CreateEqArrRow">
<xsl:param name="align" />
<xsl:param name="ndCur" />
<xsl:variable name="sAllMt">
<xsl:for-each select="$ndCur/m:t">
<xsl:value-of select="." />
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="local-name($ndCur)='r' and
namespace-uri($ndCur)='http://schemas.microsoft.com/office/omml/2004/12/core'">
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="$sAllMt" />
<xsl:with-param name="scr" select="../m:rPr[last()]/m:scr/@m:val" />
<xsl:with-param name="sty" select="../m:rPr[last()]/m:sty/@m:val" />
<xsl:with-param name="nor" select="../m:rPr[last()]/m:nor/@m:val" />
<xsl:with-param name="align" select="$align" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$ndCur" />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="count($ndCur/following-sibling::*) > 0">
<xsl:variable name="cAmp">
<xsl:call-template name="CountAmp">
<xsl:with-param name="sAllMt" select="$sAllMt" />
<xsl:with-param name="cAmp" select="0" />
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="CreateEqArrRow">
<xsl:with-param name="align" select="($align+($cAmp mod 2)) mod 2" />
<xsl:with-param name="ndCur" select="$ndCur/following-sibling::*[1]" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="CountAmp">
<xsl:param name="sAllMt" />
<xsl:param name="cAmp" />
<xsl:choose>
<xsl:when test="string-length(substring-after($sAllMt, '&')) > 0 or
substring($sAllMt, string-length($sAllMt))='&'">
<xsl:call-template name="CountAmp">
<xsl:with-param name="sAllMt" select="substring-after($sAllMt, '&')" />
<xsl:with-param name="cAmp" select="$cAmp+1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$cAmp" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template: ParseEqArrMr
Similar to ParseMt, but this one has to do more for an equation
array. The presence of & in a run that is in an equation array
indicates alignment
-->
<xsl:template name="ParseEqArrMr">
<xsl:param name="sToParse" />
<xsl:param name="sty" />
<xsl:param name="scr" />
<xsl:param name="nor" />
<xsl:param name="align" />
<xsl:if test="string-length($sToParse) > 0">
<xsl:choose>
<xsl:when test="substring($sToParse,1,1) = '&'">
<xsl:choose>
<xsl:when test="$align='0'">
<mml:maligngroup />
</xsl:when>
<xsl:when test="$align='1'">
<mml:malignmark>
<xsl:attribute name="edge">left</xsl:attribute>
</mml:malignmark>
</xsl:when>
</xsl:choose>
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="substring($sToParse,2)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="align">
<xsl:choose>
<xsl:when test="$align='1'">0</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="sRepNumWith0">
<xsl:call-template name="SReplaceNumWithZero">
<xsl:with-param name="sToParse" select="$sToParse" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="sRepOperWith-">
<xsl:call-template name="SReplaceOperWithMinus">
<xsl:with-param name="sToParse" select="$sRepNumWith0" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="iFirstOper" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '-'))" />
<xsl:variable name="iFirstNum" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '0'))" />
<xsl:variable name="iFirstAmp" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '&'))" />
<xsl:variable name="fNumAtPos1">
<xsl:choose>
<xsl:when test="substring($sRepOperWith-,1,1)='0'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fOperAtPos1">
<xsl:choose>
<xsl:when test="substring($sRepOperWith-,1,1)='-'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<!-- Case I: The string begins with neither a number, nor an operator -->
<xsl:when test="$fNumAtPos1='0' and $fOperAtPos1='0'">
<xsl:variable name="nCharToPrint">
<xsl:choose>
<xsl:when test="($iFirstOper=$iFirstNum) and
($iFirstAmp=$iFirstOper) and
($iFirstOper=string-length($sToParse)) and
$fNumAtPos1='0' and
$fOperAtPos1='0'">
<xsl:value-of select="string-length($sToParse)" />
</xsl:when>
<xsl:when test="($iFirstOper < $iFirstNum) and
($iFirstOper < $iFirstAmp)">
<xsl:value-of select="$iFirstOper - 1" />
</xsl:when>
<xsl:when test="($iFirstNum < $iFirstOper) and
($iFirstNum < $iFirstAmp)">
<xsl:value-of select="$iFirstNum - 1" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$iFirstAmp - 1" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<mml:mi>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="nCharToPrint" select="$nCharToPrint" />
<xsl:with-param name="sTokenType" select="'mi'" />
</xsl:call-template>
<xsl:value-of select="substring($sToParse,1,$nCharToPrint)" />
</mml:mi>
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="substring($sToParse, $nCharToPrint+1)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="align" select="$align" />
</xsl:call-template>
</xsl:when>
<!-- Case II: There is an operator at position 1 -->
<xsl:when test="$fOperAtPos1='1'">
<mml:mo>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" />
<xsl:with-param name="sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="sTokenType" select="'mo'" />
</xsl:call-template>
<xsl:value-of select="substring($sToParse,1,1)" />
</mml:mo>
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="substring($sToParse, 2)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="align" select="$align" />
</xsl:call-template>
</xsl:when>
<!-- Case III: There is a number at position 1 -->
<xsl:otherwise>
<xsl:variable name="sConsecNum">
<xsl:call-template name="SNumStart">
<xsl:with-param name="sToParse" select="$sToParse" />
<xsl:with-param name="sPattern" select="$sRepNumWith0" />
</xsl:call-template>
</xsl:variable>
<mml:mn>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" />
<xsl:with-param name="sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="sTokenType" select="'mn'" />
</xsl:call-template>
<xsl:value-of select="$sConsecNum" />
</mml:mn>
<xsl:call-template name="ParseEqArrMr">
<xsl:with-param name="sToParse" select="substring-after($sToParse, $sConsecNum)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="align" select="$align" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<!-- %%Template: ParseMt
Produce a run of text. Technically, OMML makes no distinction
between numbers, operators, and other characters in a run. For
MathML we need to break these into mi, mn, or mo elements.
See also ParseEqArrMr
-->
<xsl:template name="ParseMt">
<xsl:param name="sToParse" />
<xsl:param name="sty" />
<xsl:param name="scr" />
<xsl:param name="nor" />
<xsl:if test="string-length($sToParse) > 0">
<xsl:variable name="sRepNumWith0">
<xsl:call-template name="SReplaceNumWithZero">
<xsl:with-param name="sToParse" select="$sToParse" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="sRepOperWith-">
<xsl:call-template name="SReplaceOperWithMinus">
<xsl:with-param name="sToParse" select="$sRepNumWith0" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="iFirstOper" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '-'))" />
<xsl:variable name="iFirstNum" select="string-length($sRepOperWith-) - string-length(substring-after($sRepOperWith-, '0'))" />
<xsl:variable name="fNumAtPos1">
<xsl:choose>
<xsl:when test="substring($sRepOperWith-,1,1)='0'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fOperAtPos1">
<xsl:choose>
<xsl:when test="substring($sRepOperWith-,1,1)='-'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<!-- Case I: The string begins with neither a number, nor an operator -->
<xsl:when test="$fOperAtPos1='0' and $fNumAtPos1='0'">
<xsl:variable name="nCharToPrint">
<xsl:choose>
<xsl:when test="($iFirstOper=$iFirstNum) and
($iFirstOper=string-length($sToParse)) and
(substring($sRepOperWith-, string-length($sRepOperWith-))!='0') and
(substring($sRepOperWith-, string-length($sRepOperWith-))!='-')">
<xsl:value-of select="string-length($sToParse)" />
</xsl:when>
<xsl:when test="$iFirstOper < $iFirstNum">
<xsl:value-of select="$iFirstOper - 1" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$iFirstNum - 1" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<mml:mi>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="nCharToPrint" select="$nCharToPrint" />
<xsl:with-param name="sTokenType" select="'mi'" />
</xsl:call-template>
<xsl:value-of select="substring($sToParse,1,$nCharToPrint)" />
</mml:mi>
<xsl:call-template name="ParseMt">
<xsl:with-param name="sToParse" select="substring($sToParse, $nCharToPrint+1)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
</xsl:call-template>
</xsl:when>
<!-- Case II: There is an operator at position 1 -->
<xsl:when test="$fOperAtPos1='1'">
<mml:mo>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" />
<xsl:with-param name="sty" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="sTokenType" select="'mo'" />
</xsl:call-template>
<xsl:value-of select="substring($sToParse,1,1)" />
</mml:mo>
<xsl:call-template name="ParseMt">
<xsl:with-param name="sToParse" select="substring($sToParse, 2)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
</xsl:call-template>
</xsl:when>
<!-- Case III: There is a number at position 1 -->
<xsl:otherwise>
<xsl:variable name="sConsecNum">
<xsl:call-template name="SNumStart">
<xsl:with-param name="sToParse" select="$sToParse" />
<xsl:with-param name="sPattern" select="$sRepNumWith0" />
</xsl:call-template>
</xsl:variable>
<mml:mn>
<xsl:call-template name="CreateTokenAttributes">
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="'p'" />
<xsl:with-param name="nor" select="$nor" />
<xsl:with-param name="sTokenType" select="'mn'" />
</xsl:call-template>
<xsl:value-of select="$sConsecNum" />
</mml:mn>
<xsl:call-template name="ParseMt">
<xsl:with-param name="sToParse" select="substring-after($sToParse, $sConsecNum)" />
<xsl:with-param name="scr" select="$scr" />
<xsl:with-param name="sty" select="$sty" />
<xsl:with-param name="nor" select="$nor" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<!-- %%Template: SNumStart
Return the longest substring of sToParse starting from the
start of sToParse that is a number. In addition, it takes the
pattern string, which is sToParse with all of its numbers
replaced with a 0. sPattern should be the same length
as sToParse
-->
<xsl:template name="SNumStart">
<xsl:param name="sToParse" select="''" />
<xsl:param name="sPattern" select="'$sToParse'"/> <!-- if we don't get anything, take the string itself -->
<xsl:choose>
<!-- the pattern says this is a number, recurse with the rest -->
<xsl:when test="substring($sPattern, 1, 1) = '0'">
<xsl:call-template name="SNumStart">
<xsl:with-param name="sToParse" select="$sToParse" />
<xsl:with-param name="sPattern" select="substring($sPattern, 2)" />
</xsl:call-template>
</xsl:when>
<!-- the pattern says we've run out of numbers. Take as many
characters from sToParse as we shaved off sPattern -->
<xsl:otherwise>
<xsl:value-of select="substring($sToParse, 1, string-length($sToParse) - string-length($sPattern))" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template SRepeatCharAcc
The core of SRepeatChar with an accumulator. The current
string is in param $acc, and we will double and recurse,
if we're less than half of the required length or else just
add the right amount of characters to the accumulator and
return
-->
<xsl:template name="SRepeatCharAcc">
<xsl:param name="cchRequired" select="1" />
<xsl:param name="ch" select="'-'" />
<xsl:param name="acc" select="$ch" />
<xsl:variable name="cchAcc" select="string-length($acc)" />
<xsl:choose>
<xsl:when test="(2 * $cchAcc) < $cchRequired">
<xsl:call-template name="SRepeatCharAcc">
<xsl:with-param name="cchRequired" select="$cchRequired" />
<xsl:with-param name="ch" select="$ch" />
<xsl:with-param name="acc" select="concat($acc, $acc)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($acc, substring($acc, 1, $cchRequired - $cchAcc))" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- %%Template SRepeatChar
Generates a string nchRequired long by repeating the given character ch
-->
<xsl:template name="SRepeatChar">
<xsl:param name="cchRequired" select="1" />
<xsl:param name="ch" select="'-'" />
<xsl:call-template name="SRepeatCharAcc">
<xsl:with-param name="cchRequired" select="$cchRequired" />
<xsl:with-param name="ch" select="$ch" />
<xsl:with-param name="acc" select="$ch" />
</xsl:call-template>
</xsl:template>
<!-- %%Template SReplaceOperWithMinus
Go through the given string and replace every instance
of an operator with a minus '-'. This helps quickly identify
the first instance of an operator.
-->
<xsl:template name="SReplaceOperWithMinus">
<xsl:param name="sToParse" select="''" />
<xsl:value-of select="translate($sToParse, $sOperators, $sMinuses)" />
</xsl:template>
<!-- %%Template SReplaceNumWithZero
Go through the given string and replace every instance
of an number with a zero '0'. This helps quickly identify
the first occurence of a number.
Considers the '.' and ',' part of a number iff they are sandwiched
between two other numbers. 0.3 will be recognized as a number,
x.3 will not be. Since these characters can also be an operator, this
should be called before SReplaceOperWithMinus.
-->
<xsl:template name="SReplaceNumWithZero">
<xsl:param name="sToParse" select="''" />
<!-- First do a simple replace. Numbers will all be come 0's.
After this point, the pattern involving the . or , that
we are looking for will become 0.0 or 0,0 -->
<xsl:variable name="sSimpleReplace" select="translate($sToParse, $sNumbers, $sZeros)" />
<!-- And then, replace 0.0 with just 000. This means that the . will
become part of the number -->
<xsl:variable name="sReplacePeriod">
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sSimpleReplace"/>
<xsl:with-param name="sOrig" select="'0.0'"/>
<xsl:with-param name="sReplacement" select="'000'"/>
</xsl:call-template>
</xsl:variable>
<!-- And then, replace 0,0 with just 000. This means that the , will
become part of the number -->
<xsl:call-template name="SReplace">
<xsl:with-param name="sInput" select="$sReplacePeriod"/>
<xsl:with-param name="sOrig" select="'0,0'"/>
<xsl:with-param name="sReplacement" select="'000'"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>